package com.tencent.crazypenguin.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.struts2.ServletActionContext;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

//by pluschen 2016-6-25

public class JsonUtil {
	public static JSONObject getJsonFromInputstream(InputStream in) throws Exception
	{
		JSONObject json = new JSONObject();
		
		BufferedReader bufreader = new BufferedReader(new InputStreamReader(in,"UTF-8"));
		StringBuffer jsonstr=new StringBuffer();
		String temp = null;
		while((temp=bufreader.readLine())!=null) jsonstr.append(temp);
		bufreader.close();
		System.out.println(jsonstr);
		if(!JsonUtil.mayBeJSON(jsonstr.toString()))
			throw new Exception("postData not a json"+"="+jsonstr);
		json = JSONObject.fromObject(jsonstr.toString());

		return json;
	}
	
	public static JSONObject getPostData() throws IOException, Exception{
		
		
		return JsonUtil.getJsonFromInputstream(ServletActionContext.getRequest().getInputStream());
		
	}
	
	
	public static String format(String jsonStr) {
	    int level = 0;
	    StringBuffer jsonForMatStr = new StringBuffer();
	    for(int i=0;i<jsonStr.length();i++){
	      char c = jsonStr.charAt(i);
	      if(level>0&&'\n'==jsonForMatStr.charAt(jsonForMatStr.length()-1)){
	        jsonForMatStr.append(getLevelStr(level));
	      }
	      switch (c) {
	      case '{': 
	      case '[':
	        jsonForMatStr.append(c+"\n");
	        level++;
	        break;
	      case ',': 
	        jsonForMatStr.append(c+"\n");
	        break;
	      case '}':
	      case ']':
	        jsonForMatStr.append("\n");
	        level--;
	        jsonForMatStr.append(getLevelStr(level));
	        jsonForMatStr.append(c);
	        break;
	      default:
	        jsonForMatStr.append(c);
	        break;
	      }
	    }
	    
	    return jsonForMatStr.toString();

	  }
	  
	  private static  String getLevelStr(int level){
	    StringBuffer levelStr = new StringBuffer();
	    for(int levelI = 0;levelI<level ; levelI++){
	      levelStr.append("\t");
	    }
	    return levelStr.toString();
	  }
	  
	  public static String replaceControlChar(StringBuffer str) {
		  String dest = "";
	        if (str!=null) {
	            Pattern p = Pattern.compile("\\s*|\t|\r|\n");
	            Matcher m = p.matcher(str);
	            dest = m.replaceAll("");
	        }
	        return dest;
	    }
	  
	   /**
       * 该字符串可能转为 JSONObject 或 JSONArray
       * @param string
       * @return
       */
      public static boolean mayBeJSON(String string) {
          return ((string != null) && ((("null".equals(string))
                  || ((string.startsWith("[")) && (string.endsWith("]"))) || ((string
                  .startsWith("{")) && (string.endsWith("}"))))));
      }
       
      /**
       * 该字符串可能转为JSONObject
       * @param string
       * @return
       */
      public static boolean mayBeJSONObject(String string) {
          return ((string != null) && ((("null".equals(string))
                   || ((string.startsWith("{")) && (string.endsWith("}"))))));
      }
       
      /**
       * 该字符串可能转为 JSONArray
       * @param string
       * @return
       */
      public static boolean mayBeJSONArray(String string) {
          return ((string != null) && ((("null".equals(string))
                  || ((string.startsWith("[")) && (string.endsWith("]"))))));
      }
      
      /**
       *函数注释：parseJSON2Map()<br>
       *时间：2014-10-28-上午10:50:21<br>
       *用途：该方法用于json数据转换为<Map<String, Object>
       *@param jsonStr
       *@return
       */
         @SuppressWarnings({ "unchecked", "rawtypes" })
         public static Map<String, Object> parseJSON2Map(String jsonstring){      	     
        	        Stack<Map> maps=new Stack<Map>(); //用来表示多层的json对象
        	        Stack<List> lists=new Stack<List>(); //用来表示多层的list对象
        	        Stack<Boolean> islist=new Stack<Boolean>();//判断是不是list
        	        Stack<String> keys=new Stack<String>(); //用来表示多层的key
        	         
        	        boolean hasyinhao=false;
        	        String keytmp=null;
        	        Object valuetmp=null;
        	        StringBuilder builder=new StringBuilder();
        	        char[] cs=jsonstring.toCharArray();
        	         
        	        for (int i = 0; i < cs.length; i++) {
        	             
        	            if(hasyinhao){
        	                if(cs[i]!='\"'&&cs[i]!='\'')
        	                    builder.append(cs[i]);
        	                else
        	                    hasyinhao=false;
        	                 
        	                continue;
        	            }
        	            switch (cs[i]) {
        	            case '{': //如果是{map进栈
        	             
        	                maps.push(new HashMap());
        	                islist.push(false);
        	                continue;
        	            case '\'':
        	            case '\"':
        	                hasyinhao=true;
        	                continue;
        	            case ':'://如果是：表示这是一个属性建，key进栈
        	                 
        	                keys.push(builder.toString());
        	                builder=new StringBuilder();
        	                continue;
        	            case '[':
        	             
        	                islist.push(true);
        	                lists.push(new ArrayList());
        	                continue;
        	            case ','://这是一个分割，因为可能是简单地string的键值对，也有可能是string=map
        	            //的键值对，因此valuetmp 使用object类型；
        	            //如果valuetmp是null 应该是第一次，如果value不是空有可能是string，那是上一个键值对，需要重新赋值
        	            //还有可能是map对象，如果是map对象就不需要了
        	                 
        	                boolean listis=islist.peek();
        	                 
        	                if(builder.length()>0)
        	                    valuetmp=builder.toString();
        	                builder=new StringBuilder();
        	                if(!listis){
        	                    keytmp=keys.pop();                  
        	                    maps.peek().put(keytmp, valuetmp);
        	                }else
        	                    lists.peek().add(valuetmp);
        	                 
        	                continue;
        	            case ']':
        	             
        	                islist.pop();
        	                 
        	                if(builder.length()>0)
        	                    valuetmp=builder.toString();
        	                builder=new StringBuilder();
        	                lists.peek().add(valuetmp);
        	                valuetmp=lists.pop();
        	                continue;
        	            case '}':
        	             
        	                islist.pop();
        	                //这里做的和，做的差不多，只是需要把valuetmp=maps.pop();把map弹出栈
        	                keytmp=keys.pop();
        	                 
        	                if(builder.length()>0)
        	                    valuetmp=builder.toString();
        	             
        	                builder=new StringBuilder();
        	                maps.peek().put(keytmp, valuetmp);
        	                valuetmp=maps.pop();
        	                continue;
        	            default:                
        	                builder.append(cs[i]);
        	                continue;
        	            }
        	             
        	        }       
        	        return (Map<String, Object>) valuetmp;
        	    }
          
         /**
               * 函数注释：parseJSON2MapString()<br>
           * 用途：该方法用于json数据转换为<Map<String, String><br>
           * 备注：***<br> 
           */
         public  static Map<String, String> parseJSON2MapString(JSONObject json){  
             Map<String, String> map = new HashMap<String, String>();  
             //最外层解析  
//             JSONObject json = JSONObject.fromObject(jsonStr);  
             for(Object k : json.keySet()){ 
                 Object v = json.get(k);   
                 if(null!=v){
                     map.put(k.toString(), v.toString());  
                 }
             }  
             return map;  
         }
         
         /**
          *函数注释：parseJSON2List()<br>
          *用途：该方法用于json数据转换为List<Map<String, Object>><br>
          */
          @SuppressWarnings("unchecked")
		public static List<Map<String, Object>> parseJSON2List(JSONArray jsonArr){  
//                 JSONArray jsonArr = JSONArray.fromObject(jsonStr);  
                 List<Map<String, Object>> list = new ArrayList<Map<String,Object>>();  
                 Iterator<JSONObject> it = jsonArr.iterator();  
                 while(it.hasNext()){  
                     JSONObject json2 = it.next();  
                     list.add(parseJSON2Map(json2.toString()));  
                 }  
                 return list;  
             }
           
         /**
         * 函数注释：parseJSON2ListString()<br>
         * 用途：该方法用于json数据转换为List<Map<String, String>><br>
         */
          @SuppressWarnings("unchecked")
		public static List<Map<String, String>> parseJSON2ListString(JSONArray jsonArr){  
//                     JSONArray jsonArr = JSONArray.fromObject(jsonStr);  
                     List<Map<String, String>> list = new ArrayList<Map<String,String>>();  
                     Iterator<JSONObject> it = jsonArr.iterator();  
                     while(it.hasNext()){  
                         JSONObject json2 = it.next();  
                         list.add(parseJSON2MapString(json2));  
                     }  
                     return list;  
                 }

}
